                       Comic Strip

         Clyde Bish [writes] a three part series
            showing how you can produce your
             own computerised cartoon strip.

[ This series was published in the last three issues of
  ZX Computing, from April to June 1987. This file con-
  tains the text of all three articles, with some changes
  where necessary to address the fact that this isn't a
  three-month series with listings, but a text file with
  accompanying TZX. These changes are indicated by square
  brackets. Any other remarks of my own, not part of the
  original text, are similarly noted.
  In the same place where you found this text file, there
  should also be a "Comic Strip Figure 1.png", which is an
  illustration referred to in part one, and either three
  separate "Comic Strip part X.tzx" files or just the one
  "Comic Strip.tzx", which contains everything from the
  three smaller TZXes.
                                Richard Bos, Januari 2012 ]

The medium of the comic strip has always been a popular
one. Hands up anyone who hasn't followed the exploits of
Dennis the Menace, Batman, Judge Dredd, of, for more mature
ZXC readers, that "strip" heroine, Jane! In fact, PhD's
have been awarded on analyses of the exploits of Asterix
and Co. It is also a medium which lends itself readily to
the computer screen - Melbourne House's Redhawk, for
example - so let's switch on the machinery, and the grey
matter, and see what facilities are required.
   Obviously we need the strip itself, ideally scrolling
right to left, with the new illustration being drawn in the
space vacated screen right. In addition to the actual
picture we will also need captions, and perhaps speech
bubbles. We'll also need an on-screen input systems to a
vertically scrolling communications window, indications of
strength, stamina etc. for an adventure (or profits, stocks
held etc. for a strategy game) and perhaps a real-time
clock and, in a "Superman"-type strip, a visual reminder of
your persona at any given time.
   With these requirements I came up with a screen display
like that shown in Fig. 1. [There should be a 'Comic Strip
Figure 1.png' where you found this text.] I emphasise that
this is just a suggestion - you will be writing the program
which uses the strip so you must decide on the final
display format, and the purpose of this series is to show
you how.

 Piccies

Let's start this [part] with the illustrations. Look at a
strip cartoon and you'll see that it's made up of three
'layers'. Furthest back is, not surprisingly, the back-
ground. This is usually a fairly simple line drawing with
various embellishments such as pictures on a wall or
flaming torches as in Fig. 1. In front of this, often in a
multi-layered format, are the characters. (So we don't
confuse these characters with the character symbols we'll
be printing as embellishments I'll call the former
"icons"). Finally comes the speech bubble.
   Bearing this in mind we obviously need a similar system
for a computer strip, each element taking up as little
memory space as possible. Since a background or icon may be
used more than once in a story line it would be uneconomic
to store each complete illustration separately. Instead,
we'll hold each element as a series of bytes in memory and
call them, more or less as subroutines, when needed by a
driver routine.
   Let's get the necessary machine code on board first.
CLEAR 64935, type in the loader (Program 1) [A slightly
modified version of this is "loader" on the TZX], setting
the from and end values to 64936 and 65375 respectively,
then RUN and enter the numbers from Table A, reading across
each line. Save the code with:
  SAVE "drawCODE" CODE 64936,440
and verify.

 Drawing

Let's begin with an explanation of the background drawing
routine. This, remember, is made up of two elements: the
line drawing, and the embellishments (torches and mystic
symbols over the door in my example screen). The line
drawing data is held as a series of PLOT or DRAW co-ordi-
nates. Each set starts with a PLOT pair and continues with
a number of DRAW pairs. The DRAW co-ordinates are absolute,
i.e. the actual co-ordinates of the pixels you want to draw
to, not offset values as in the Basic DRAW. This makes
inputting values from a drawing on pixel paper much easier.
When the routine finds a 1 the next pair starts a new PLOT
position. A terminal 0 is needed to return from the
routine.
   To use this elemend, the data (PLOTs, DRAWs, 1s and 0s)
are held in a series of bytes starting at a known address,
say 50000, and the routine is called with a line such as:
  10 POKE 23296,80: POKE 23297,195: RANDOMIZZE USR 65197
The POKEs (into the first two bytes of the Printer Buffer)
are the low and high values of the data start address
(80 + 195*256 = 50000). Look at the beginning of Table B,
the data we'll use for the demonstration at the end, and
you'll see the 1s which reset the PLOT position and the 0
to return. [You'll find Tables B and C at the end of this
part. I have omitted Table A, as it's just machine code and
not interesting to read in decimal form. It's on the TZX,
of course, as "drawCODE".]
   The remainder of the elements are called with a single
USR call. Don't try to link these routines with the back-
ground in a single call. The routine will crash! This call
produces the embellishments, the icons and the speech
bubble. The information to control the printing (but not
the data itself) is held in a string of numbers as follows:

a) Embellishments - A 0 to start means miss out this ele-
ment. Any other number is the total number of this type of
element to be printed, so in Fig. 1 this would be '3' as
there are two torches and the mystic symbol block to print.
There then follows a series of numbers in blocks of three.
The first of these is the length of the data block (maxi-
mum 255), which begins at the address given by the next two
numbers. So the sequence:
 3, 7,80,195, 10,180,195, 6,200,195
would print three objects. The first is madde up of 7 bytes
of data beginning at 80 + 195*256 = 50000. The remaining
numbers would translate in a similar way.

b) Icons - As before, a starting 0 means miss out this
element. Any other number is the total number of icons to
print. (For Fig. 1 this would be '2' - one for the troll
and one for the background character.) This number is
followed by others in blocks of five. The first number in
each block is the Print At row, the second the column, the
third and fourth the address (held as before) and the fifth
is the type of icon shape. There are three types of icon
available. Type 0 is three characters wide by four high,
for small characters like the troll. Type 1 is four wide by
figh high, and type 2 is a 6x6 grid for close-ups (or two
small characters which always appear together). Each is
printed in such a way as not to obliterate the background
where no icon pixels are being filled. The sequence:
 2, 1,4,80,195,0, 2,10,180,195,2
would print two icons, the first a 3x4 block with top left
corner at row 1, column 4, from data starting at 50000.
I'll leave you to work out the second. Note that this mode
only operates within the top third of the screen. If the
bottom of a block comes below row 7 strange things will
happen!

c) Speech Bubble - Again 0 means miss out, otherwise the
first (and only) digit refers to the column where the
pointer V is to be printed. (In Fig. 1 it's at column 28.)
The start of such a control string is POKEd into 64942 (low
byte( and 64943 *high byte) before calling the routine with
RANDOMIZE USR 64936.

 Data

Now to the actual data to which the control string refers.

a) Embellishments - This is held as:
22, row, column, codes of characters to be printed (see
Appx. A of your Spectrum manual) resetting with 22,row,
column whenever a new print position is required. So the
data string:
 22,1,0,48,49,50, 22,2,5,65,66
(which, incidentally, has a length of 11 - you count the
22s as well) would print out "012" at row 1, column 0 and
"AB" at row 2, column 5. You can include block graphics or
any user-designed graphics you have made (20 are available
as A is used for the bubble pointer). You can also include
control characters (see p. 183 in the manual), so 16,2
would set INK to red, 17,6 would print on yellow paper,
19,1 would have the colours bright, and 18,1 would have
them flashing. (Try 22,row,column,18,1,134,137 for minor
"animation"!)

b) Icon data - The data for these is the actual bit pat-
terns for each screen byte to be used. Each character
square on screen is made up of eight lines of eight pixels
one below the other, but held in the computer's memory one
/after/ the other! To make matters worse they are held in a
rather strange order. To see what I mean enter the line
  FOR f=16384 TO 18432: POKE f,255: PAUSE 20: NEXT f
and watch the way the screen fills. What this amounts to
is, apparently, nothing less than confusion! It isn't,
really. Refer to Fig. 2 and you'll see that you have to
POKE in the bit pattern of each byte (using the BIN func-
tion) in the order given for a 3x4 icon. (If you're still
confused wait until [the next part] and I'll supply an
editor program to do the job for you.)

  +----------------+----------------+----------------+
  | 1              | 2              | 3              |
  | 13             | 14             | 15             |
  | 25             | 26             | 27             |
  | 37             |                | 39             |
  | 49             |                | 51             |
  | 61             |                | 63             |
  | 73             |                | 75             |
  | 85             |                | 87             |
  +----------------+----------------+----------------+
  | 4              | 5              | 6              |
  | 16             | 17             | 18             |
  | 28             |                | 30             |
  | 40             |                | 42             |
  | 52             |                | 54             |
  | 64             |                | 66             |
  | 76             |                | 78             |
  | 88             |                | 90             |
  +----------------+----------------+----------------+
  | 7              | 8              | 9              |
  | 19             | 20             | 21             |
  | 31             |                | 33             |
  | 34             |                | 45             |
  | 55             |                | 57             |
  | 67             |                | 69             |
  | 79             |                | 81             |
  | 91             |                | 93             |
  +----------------+----------------+----------------+
  | 10             | 11             | 12             |
  | 22             | 23             | 24             |
  | 34             |                | 36             |
  | 46             |                | 48             |
  | 58             |                | 60             |
  | 70             |                | 72             |
  | 82             |                | 84             |
  | 94             | 95             | 96             |
  +----------------+----------------+----------------+
  Figure 2 [and yeah, it was this wide in the magazine.]

To end, let's pull all the ideas together with a grand
demonstration of the facilities offered. We'll reproduce
the top right picture from Fig. 1, but to save on typing
we'll use just one icon, the troll, and the speech bubble
will remain empty (we'll deal with how to fill that later).
  [Load] the loader program to enter the data from Table B
from 50000 to 50131. Enter just the numbers, not the text
lines, those are to help you find your way around. Now
[run] the loader again to enter the control string data
(Table C) into addresses 60000 to 60010. [These, together,
are in "tables1" on the TZX.]
  We're almost ready to roll, but we need a line to call up
the routines. Type in Program 2 and RUN for the display.
The REMs will explain what each part does. [This is
"Demo1A" on the TZX. Note that, as the REM says, you need
all code loaded for this to work.]
  Now, what about that empty speech bubble? There are eight
character squares within it, so provided you only need that
number of spaces as a maximum you could just PRINT AT 1,23;
"text" (like the "BEGONE!!" in Fig. 1). That doesn't help
if, as is more usual, you want to display more information.
Program 3 will come to your aid. It is a basic routine for
scrolling text through a window. It takes the message
string m$, adds eight blank spaces to the front (to make
the bubble start empty) then uses a loop, set to the origi-
nal length of the string, to print successive sections of
the new string in the speech bubble. Pressing SPACE at any
time during the scroll will restart it. Add it to your
driver (Program 2) and try it out [The result (which still
needs both sets of code) is "Demo1B" on the TZX.]

-----------------------------------
  Table B

  Background data

  176 175 199 168 232 168 232 127
  199 127 199 168 1   233 168 255
  175 1   232 127 255 112 1   199
  127 176 112  0

  Embellishment data

  22  2   23  138 22  2   30  133

  Icon data

  0   0   0   68  17  0   95  125
  0   15  120 0   0   0   0   84
  21  0   95  253 0   15  120 0
  7   240 0   95  253 0   143 248
  128 15  120 0   7   240 0   95
  253 0   79  249 0   15  120 0
  8   8   0   95  125 0   15  120
  0   15  120 0   9   72  0   95
  253 0   15  120 0   7   112 0
  16  132 0   95  125 0   15  120
  0   15  120 0   37  210 0   95
  253 0   15  120 0   29  92  0
-----------------------------------
  Table C

  P_Torch

  1   8   108 195

  P_Icon

  1   2   26  116 195 0

  Bubble pointer

  28


-----------------------------------------------------------


[In this part] we add an editor program to unravel the
number strings and get that necessary data into memory with
the minimum of fuss. But before you set it to work, a
timely warning. Don't be in too much of a rush to get stuck
in. The editor will only help you to load the strings into
memory. It won't make them for you. That you must do.
   You must start with a good idea of what your strip is to
be about. Don't aim too high for starters. A short sequence
that, perhaps, you can add to later would be ideal to get
you going. (I experimented with the opening sequences from
a "Fighting Fantasy" book.) Next design the outline
drawings, icons, captions etc. on pixel paper. Again, don't
make your pictures too complex. Remember you're only
working in an 80x64 pixel box so the final resolution is
quite low.
   Some adventure illustrators go for highly detailed
pictures which might look good on paper, but transform into
a mess on screen. (If you have a monitor, or a non-"pixel
creep" Spectrum, you can get away with far more.) Rather go
for bold line. After all, it's atmosphere you're trying to
create. Not Art Nouveau! [Nope; more like Art Deco - RLB.]
  Now convert each drawing into a series of PLOT/DRAW co-
ordinates, the embellishments into their respective PRINT
AT co-ordinates and characters, and produce UDG banks on
tape for the icons - perhaps using a designer program.
(Remember icon type 0 uses UDGs "a" through "l" in a 3x4
matrix, whilst type 1 "a" to "t" in a 4x5 block, and type 2
uses /two/ "a" to "r" sets, reach in a 6x3 pattern for top
and bottom.)
   You will now know how long each data block needs to be -
an important point when setting each data start address
later.
   Assuming you've done this preparatory work Program 1
will help you out. I have included few error checks. The
"Panic Button" is GO TO 100, which will return you to the
menu. [Load "Editor" from the TZX] to start it up, and
you'll be asked for the address for the start of your data.
Enter this and you'll get the menu on screen, plus the
present start address. This will appear at the start of
each of the Create Data options and can be altered. You may
decide it's easier to put the data blocks in backwards,
i.e. using the highest memory block first and moving back
through the memory the required number of bytes each time,
rather than working from low to high with the whole data
block. If so you can use menu option 7, which, given the
length of the code block to be entered, will tell you where
to set the start address. Don't try to mix up both systems
or you'll get into an awful muddle!

   Now to the options:-

 1. Create/display drawcode
This, you remember, draws the outline picture. Table A
gives a suitable data block to test. (It produces the "end
of corridor" outline from last month's screen dump.) [In
fact, it's the same as the first section of Table B from
the previous part.] You begin by deciding on the start
address as outlined above. If you press just ENTER it will
remain as set. The new start address will be displayed in
decimal and in low/high byte form. This latter form you
will need to POKE into the drawCODE machine code before
calling the routine so make a note of them. You will also
get an input cue for the co-ordinate of the first PLOT
position. Pressing just ENTER now will allow you to escape
to the menu when you've finished. (It also allows you to
escape if you've got here by accident! This facility is
available on all options.)
   When you input a number the cue changes to "y co-ordi-
nate?". After that input the cure becomes "DRAW x co-ordi-
nate?", followed by "y co-ordinate?". Follow these as you
enter the sequence of DRAW co-ordinates from the first PLOT
position.
   When you want a new PLOT position, enter a 1 for the
first DRAW co-ordinate and you'll get back to PLOT. To end
the string enter a 0 for the DRAW co-ordinate and you'll be
given the option to display your drawcode. Pressing Y will
give a box top right, the size of your cartoon drawing.
Subsequently pressing any letter will build up your outline
drawing whilst displaying the co-ordinates at the bottom of
the screen. An END OF DRAWCODE message is given, followed
by a pause before you return to the new start address
display and "PLOT x co-ordinate?" cue. If you have no more
code to set up press just ENTER. You will be given an
option to list to printer. If you do this you'll note that
each 0 is followed by an address in bracket. This is the
start of the new drawcode following. You'll then return to
the menu.

 2. Create/display stringcode
This holds the information for the embellishments to the
line drawings. The option begins asking for start
addresses, then displays it to the left of a box outlining
the picture area, with the option to display the drawing on
which the embellishments will fit. This operates as in
option 1. Call up the "dead end" picture you've put in
already. (You do remember the data start address, don't
you?) You'll then be cued for the row, column and text of
the embellishment. Try row 1, column 25, character "@".
This will be displayed in the box. Answer the "More?" cue
with N and you'll get the option to print out the data
(with each 22 - the AT token code - preceded by its
address). Otherwise you will be asked if it is the same
string, in which case you will add to your picture. Try
row 1, column 28, character "@" to put a mystic sign in
both corners of the room. Alternatively, a new string (with
its start address and picture) can be created.

 3. Create/display icon
The icons are the illustrations that go onto the back-
ground. After the usual address request you'll be asked for
the icon type (0, 1 or 2) and the title of the UDG set
which holds the data. (You will have made these up before-
hand and have them on tape.) After the UDGs are loaded, the
icon will be displayed and, if the response to the "OK?"
cue is positive, then the bytes will be transferred,
beginning at the chosen memory address. You will again have
the option of a data printout, and the opportunity to
continue or escape to the menu. Remember that icon type 2
needs two 18-character sets of UDGs and so you'll need to
load twice.

 4. Create control string
This is the string which calls up each element of the
picture except the line drawing. It follows the same format
as described [in the previous part]. Again, the usual
address request precedes the routine proper.
   First you'll be asked for the number of embellishment
strings. Replying with a 0 jumps you past this call option.
Any other number sets up that loop which asks for the
length of a string, and then the address of the start of
its data. Enter this as a five figure decimal number and
the routine will convert it to its low/high byte form for
you.
   This call loop is followed by a cue for the number of
icons involved. Again 0 bypasses this call whilst any other
number sets up an input loop. For each icon you'll be cued
for the row and column of the top left corner, the data
start address and the icon type.
   Finally you'll be cued for the column of the speech
bubble pointer. 0 means no speech bubble required.
   You will then return to the "strings?" prompt ready to
start again (note the new address) or press just ENTER for
the menu.

 5. Circle data
This is a very useful option which will calculate the PLOT
and DRAW co-ordinates required to draw a circle.
   You will be asked for the x and y co-ordinates of the
centre of the circle, and the radius in pixels. The
"steps?" request relates to the number of steps required to
draw the circle. Answering 2 gives the best circle (but
requires the most data in memory), whereas a larger number
may give a polygon (which, for a large radius, may still be
acceptable). A true circle is drawn just inside for com-
parison. If you want to try again press A. D gives you a
list of the required co-ordinates to screen or printer.
M returns you to the menu.

 6. Save
The start and end addresses, and the length of the current
data block are displayed. Enter the title, start address
and length of the data block (which can be different from
that displayed if you want to save other data) and the
routine will save and verify the data code before returning
you to the menu.

So much for the pictures, but, as yet, we have no captions.
Now is the time to remedy that, but first, a little more
thought. Each picture is only 10 characters wide so with
three lines of printing below you could only have a maximum
of thirty characters, which is not very many. It is possi-
ble to get more by using a smaller character set. For exam-
ple, "Redhawk" uses half-size characters, but that may be a
bit on the small size. Let's be truly British and compro-
mise on a 42 character/line set, which gives us a few extra
spaces per line so longer words are easier to fit in.
  Now the bad news. A new character set means data for the
new-size characters - 768 bytes of it, plus the code to run
it! So [it has been saved on the TZX as "P42" CODE 64019,
917]. If you also load in "drawCODE" saved [in the first
part] you can save both together [and indeed, you'll find
them on the TZX as] "allcode" CODE 64019,1357.
   To use it you have to set the string variable z$ to the
text, and precede it with the character code for the row
and column numbers before calling the machine code. Test it
out with:
  LET z$=CHR$ 5+CHR$ 20+"test": PRINT: RANDOMIZE USR 64787
and you should get the word "test" appear at row 5, column
20 (of 42), i.e. about halfway across the screen.
   So now we have the printing technique but still need to
hold the data strings for the various captions in the least
possible memory space. The technique I've chosen is to hold
all the captions in one long string, m$, and use a pointer
p to indicate the start byte of each message. This will be
the number of lines of print in the message (1 to 30) and
is followed by that number of blocks of 12 characters - the
text of the message. To make the formation of such a string
easier, help is again at hand in the form of Program 4, a
text editor which will help you do the job. [It's on the
TZX as "Textedit".] As with the picture editor you need to
know what your messages are before you begin, so take time
to write some suitable ones, remembering that each must be
a maximum of 3 lines, each of only 12 characters. Table C
gives some possible examples.

  Table C
  Message 1. Suddenly a nasty troll appears.
  Message 2. You wait...
  Message 3. You come to a heavy wooden door.
  Message 4. You open the green door.

When you run Program 4 you'll get the option to have hard
copy. You'll then see displayed the message number you're
at and the position of the pointer along the string. You
first have to enter the number of lines for that message.
Let's try it out with 3. Now you'll get the prompt "Message
1, Line 1" with a "V" beneath. Type in the first line of a
caption such as "Suddenly a nasty troll appears!" but don't
go past the V. Enter this and continue with the second
line, and finally the last - just the word "appears!" Your
message will appear highlighted on screen before the
message/pointer display reappears, reset to the new value.
Note the pointer value if you have no hard copy. (Inciden-
tally, it's worth saving a one-line message of just 12
blank spaces as there will be occasions when you want a
picture with no caption.) When you have no further captions
to code press Enter at the "number of lines?" cue and
you'll be told the length of m$. Now save just the varia-
bles area (containing m$) by deleating each line then
saving with SAVE "m$data".
   To use this string in your final program you'll be using
a routine similar to [this:
  FOR f=1 TO VAL m$(p)
  LET z$=CHR$ (f+7)+CHR$ 29+m$(p+1 TO p+12)
  PRINT: RANDOMIZE USR 64787
  LET p=p+12
  NEXT f]
Try it out with some of the pointer values you noted for m$
(and making sure you have P42 code on board and have merged
in m$!). [You'll find a similar program, with the messages
from table C (above) pre-merged, on the TZX as "Demo2". It
will want to load "P42", which is a bit earlier on the TZX.
Pointer values you can try are 1, 38, 51, 88, and 113; the
last one is the empty message. If you try other pointer
values, the code will - unsurprisingly - crash in various
ways; if so, do not RUN (which erases m$), but GO TO 10.]


-----------------------------------------------------------

[ The following, final part was printed in the very last
  issue of ZX Computing (which was an unwanted surprise
  for a teenage geek, I can tell you). Unfortunately, this
  showed. The article was badly corrected and badly edited,
  riddled with smaller typesetting errors and larger, more
  grammatical mistakes. Clearly, the staff already knew
  that their magazine would be discontinued, and their
  hearts were no longer in it. I've tried to correct these
  faults as best I could, but it is entirely possible that
  in doing so, I've introduced new errors. Caveat lector. ]

So far we've looked at ways of quickly producing a cartoon-
style picture, with speech bubble and caption on screen,
using the minimum of memory. Now it's time to get things
moving, and the first thing we have to move is the existing
strip one picture to the left to make screen space on the
right for the new illustration. The code from Table A will
do this for you. [You'll find it on the TZX, saved as]
"LScroll" CODE 63905,114.
   If you want to try it without loading in a picture type:
  FOR f=1 TO 250: PRINT f: NEXT f
to get a block of numbers at the top of the screen, and
  RANDOMIZE USR 63905
You'll see the eleven rows scroll eleven columns to the
left, and a bar appear at column 21. To the right of the
bar is a blank space. This is where the next picture and
caption will be drawn.
   Before we go any further try this out:
  PRINT "O"; (ENTER)
What happens? Apparently nothing. Actually you have printed
an 'O', but it's in the same colour INK as the PAPER, and
so invisible, because the LScroll routine ends by setting
INK to PAPER colour. You can prove that it's there with:
  INK 0: PRINT "O" (ENTER)
and you'll see a 'O' to the right of the bar with a space
before it. That's where the first 'O' is!

 Captions

You may be wondering what the point of this is. The reason
is that it enables us to draw the next picture and caption
invisibly, then suddenly make it appear. How? Use [the code
loader with start and end of] 63858 and 63904 to load in
the code from table B. This new code will alter the attri-
butes (the data file in the machine's memory which controls
screen colours) in the picture box to black on cyan, and
those in the caption box to black on yellow, as well as
resetting global INK to black for subsequent PRINTs. In the
final control routine you'll be able to choose the picture
box colours but for the moment leave well alone and try
both code blocks out together with Program 2. You'll see
the screen fill with numbers, then scroll. The PRINT lines
will suddenly appear in the boxes, followed a moment later
by the INK reset message. This will repeat. Press BREAK
when you get bored.
   Before you go any further SAVE a copy of the attributes
code with SAVE "Attr"CODE 63858,47 just in case you get
your electricity cut off! [This is on the TZX under that
name, followed by "Demo3A". You'll need to load both code
files before running the program.]
   Now we have our pictures and captions on screen and
moving, it's about time we thought about how we are going
to hold the data addresses etc. We will need to POKE into
the various machine code blocks that will be doing the work
for us. Let's start by making a list of what we need to
know. We need the start address of the drawCODE, preferably
held in low/high byte form. We need a similar address for
the string/icon/bubble pointer data start. (In future we'll
just call this the restCODE.) We'll need the value of the
caption text pointer - the start position of the caption in
m$, and finally the value of the attriubte to fill the
picture box. The cheapest way to hold this information,
bytewise, is to use a string array set to three dimensions:
the number of pictures to be called, the number of bits of
information to be held (high/low for drawCODE, restCODE and
pointer, and attribute value, i.e. 7), the maximum length
of any bit of information (a three figure number).
   So, our array will be dimensioned p$(n,7,3) where n =
number of pictures.

 Editor

Having decided on the format, we now need to get the infor-
mation. Program 3 is an editor designed to do the job for
you. When you're ready [load "DataEditor"].
   You'll be asked first of all whether you want hard copy
(y/n), then for the number of pictures you need to cater
for. This will set the array and start up the loop. As the
loop runs you'll be asked for the drawCODE start address of
the picture. Enter the five-figure decimal address and the
program will convert it to its low/high byte form and store
it in p$(n,1) and p$(n,2).
   Follow this with the restCODE start address (to be
stored in p$(n,3) and p$(n,4)), the Caption Start Pointer
value (stored in p$(n,5) and p$(n,6)) and lastly the attri-
bute value (stored in p$(n,7)). To calculate this enter
PAPER * 8 + INK. The loop will repeat for each picture up
to the value set for n, before SAVEing the DATA array under
the title "picdata".
   It may have crossed your mind that there may be occa-
sions when you don't want any background drawn - perhaps
when a character is conversing in close-up. What we will do
here is to craftily PLOT and DRAW a point within the black
picture frame so that it won't show. What is even more
crafty is to use 16235 as the drawCODE start adderss. "Hold
on," I hear you say. "That's in the ROM!" Yes, I know it
is, but that doesn't matter. It just so happens that at
this address there is a series of bytes 84, 84, 84, 84, 0,
which is just what we need! Similarly, if you only want a
line drawing, set restCODE start address to 64019 - there's
a string of 0s there. As for no caption, remember I sug-
gested you made the opening substring of m$ twelve blank
spaces? It is that pointer value you give.
   In order to run all the codes in the correct order
you'll need to include Program 4 as a subroutine within
your adventure program. To change pictures you set n to the
picture number then call the routine. Line 9000 passes the
values stored in p$() to the various machine code blocks
whilst the present picture is still on screen. Line 9001
begins the change, scrolling the picture, calling the DRAW
and REST routines, and using the values in m$ to produce
the caption. ATTR make all appear from nowhere before the
routine returns. [As evident from the above, this routine
is at line 9000. However, so are several other bits of code
in this article, including what should be the main input
routine. Therefore, I've put this one at line 8000; it's on
the TZX as "showpic".]
   So now we have all the codes and controls needed to
produce and move our pictures and captions, plus scroll
speech bubbles, but that's not all we need to be able to
do. Next we need an INPUT to the main screen routine in
response to the program flow, and ideally one which will
scroll those inputs up within a communications window so we
can keep some record of passing events.
  First [load from the TZX] "UScroll" CODE 63810,48. Now
type in Program 5 (which we'll add to later) and RUN.
[This program is on the TZX as "input" with the additions
already inserted.] You'll see a flashing cursor at line 20.
Type something in. Try deleting. When you've said enough
(30 characters is the limit) press enter. Your input will
scroll up one row. If you repeat the input test five more
times you'll see the top message move up each time until,
on the last move, it disappears, having scrolled out of
the box.

 Clock

Well, those are the main routines you'll need, but there
are many others you could use. For eample, how about incor-
porating an on-screen timer into the input routine? This is
quite easy to do using the computer's on-board clock. Its
values are held in a system variable called FRAMES, which
counts the passage of time in 1/50th seconds. Here's how to
make it work. [Two bits of code would be added to the input
routine here; as I've said above, "input" on the TZX has
already had them added.] Each time you GOSUB to, or leave,
the input routine you will update the timer. Of course you
can update the timer at any time just by calling the sub-
routine. You could, for example, also update the timer by
including a call within the picture subroutine listed
earlier. The principle of the timer is quite simple. If you
want an explanation of the functions look up p. 99 in your
manual. The remainder of the routine takes that value, t,
and converts it to hours and minutes before printing to
screen in the Time box. As the timer is set to 0 at the
start you can check the value of it to see if a particular
event has taken place within a given time limit.
   Usually within an adventure you have a limited amount of
strength or whatever which is decreased by conflicts or
time and increased by food and spells etc. It would be use-
ful to know how you were faring so let's arrange for an
on-screen bar chart of strength levels. There are two ways
to do this. Which you choose depends on whether you want
to use character-sized blocks or pixel width bars and so
get a finer graph. First is the block time. Program 7(a) is
called at line 1000 for a decrease in strength (and sub-
sequent decrease in bar length) and at line 1010 for in-
crease in strength. There's no requirement to use graphic
blocks as indicated in the program. You might prefer a half
bar, or in fact, any character (e.g. a  sign for money) or
design and use a UDG. If you POKE the data 102, 153, 129,
129, 66, 66, 36 & 24 into a UDG memory block you will have
a heart shape to use for popularity or love.
   The pixel-bar type is shown in Program 7(b). It uses
PLOT and OVER 1 to produce the graph. If you call the rou-
tine more than once (by using a loop within it) you can
produce wider bars. [These snippets were printed in the
magazine at line 9000. Above, they're described as being
at line 1000. However, the next bit will also be running
from line 1000. Therefore, I've put these two on the TZX
(as "blockgraph" and "pixelgraph") at line 7000. They're at
the same address, because it is unlikely you'll want to use
both in one program.]
   Now, how about a schizophrenic hero who, like Superman
et al, can change persona? It is important for the player
to know who he is at any time and this could be shown as a
graphic in a box centre right of screen. First we need the
graphics data in memory. As the bock is 4x3 characters,
this means 96 bytes of data for each of two graphics. My
schizophrenic oscillates between a handsome prince who
turns into a frog. (Well, what you you think this is? A
fairy story!) The data for these graphics is held below
the UScroll code from addresses 63618 to 63809. If you want
to see how this routine would work put in the data from
Table D between these addresses. (If you also LOAD in all
the other codes and data you have saved - AllCode, LScroll,
Attr & UScroll) you can save them now as a single block
with
  SAVE "Stripcode"CODE 63618,1758
but don't forget to CLEAR 63617 before loading it!)
   Now to see the Prince transform. We're going to use
PRINT AT with UDGs "a" to "l". "Just a moment!" I hear you
cry. "UDGs start at address 65368, not where we've loaded
the data!" Quite right.
   So, before we can PRINT anything we have to convince the
machine that the UDGs begin where we've put the data. We do
this by POKEing the system variable UDG with the low/high
bytes of the address we are using. Program 8 will do this
before PRINTing the appropriate persona. You need to call
it at line 1000 for the Frog and line 1001 to change this
amphibian into the handsome Prince. [This is on the TZX as
"transform", preceded by "Stripcode", which it needs.]
   To get the main program to call the correct routine is
easier than you think. All you need to do is to LET z = 0
when you initialise the program, then include the
subroutine
  LET z=z=0: GO SUB 1000+z: RETURN
to call when you want to make the change. That line may not
make much sense to you, but it does to the computer. It
uses what is called logic. If z = 0 then the statement
following the first = sign is true, so z will become 1 and
the PRINT routine at 1001 is called. The next time, (z = 0)
is false so z is reset to 0. Understand that or not, I
assure you it works. Try it out! Obviously the value of z
indicates the current persona which may influence your
character's capabilities and actions. (Beautiful Princesses
only kiss frogs, not handsome Princes!)

Now we have all the generat routine on board let's turn our
attention to some specific examples you'll be sure to need.

 LOOK
This is where you've forgotten where you are and want to
see the picture and caption again. Try something like a
close up of your hero with a "WHERE AM I?" bubble, but no
caption, followed by a second close-up picture with the
caption "You look carefully around." The go back to the
original location picture and caption.

 WAIT
Here you could use a close-up of your hero with the bubble
"I'M WAITING." and the caption "Time passes..."

 EAT
As wel as a close-up and a bubble such as "THAT'S YUMMY.",
don't forget to increase the strength variable and
on-screen bar, plus perhaps a caption "Your strength
increases."

 CAN'T DO THAT
A picture for general use in this sort of situation would
be a hero close-up with the bubble "SORRY, I CAN'T DO
THAT."

 INVENTORY
Try this sequence:
a) Close-up and caption "You look on your person."
b) Kneeling icon with rucksack and the caption "You look in
your rucksack."
c) If there is nothing to list use a close-up with a
"NOTHING" bubble, otherwise print up (in a sequence of
frames if necessary) what you have. (You could use the
PRINT machine code for this if you reuse the routine within
line 9001, altering the PRINT positions.)

There are many other actions and situations you'll need to
control. Those I'll leave up to you. After all, it is YOUR
adventure!
   Now to end, a hints and tips section for those know-
ledgeable and/or brave readers who want to alter the screen
layout.
   Program 9 will give you the basic screen layout my
routines work on. [It's on the TZX as "layout". A "Fig. 1"
was mentioned here, but since it was missing from the maga-
zine, I can't provide a scan of it.] Changing some of this
is easy. For example, the position of the clock, strength
bars etc. and persona icon (if you want them at all) can be
changed by altering PRINT AT positions once you search them
out in the subroutines. Less simple are alterations to
machine code routines, so I'll need to check these out in
more detail.

 Picture Size
This is set at ten character squares wide. To change this
you need to POKE 63861 and 63872 with the new width, and
63906 with the new value + 1. The vertical bar printed by
LScroll is of graphic blocks. To change the character (you
could design a UDG), POKE the character code into 64008. It
also defaults to black INK. If you want a different colour
(to match, say, a blue border) include INK i at the start
of Program 4 ["showpic"], where i = INK colour. You can
also increase the caption area by POKEing 63873 with the
height. (You may also need to make alterations in the
number of lines allowed in the text editor.) Don't forget
to lengthen the bar printed by LScroll. POKE 63998 with the
new value. If you're not using black ink on yellow paper
you'll also have to POKE your attribute value into 64014
and 63881.
   As written the routine produces a two-tone picture - INK
and PAPER. If you want to introduce more colour or other
attributes you can do this using a line such as
  PRINT AT row,column; OVER 1; INK/PAPER/BRIGHT/FLASH
  number; "spaces equal to the number of characters you
  wish to affect"
after the Program 4 routine has RETURNed. So, in the first
screen dump shown with the troll, you could make the mystic
symbols over the open door flash bright blue ink on yellow
paper with
  PRINT AT 1,15; OVER 1; INK 1; BRIGHT 1; PAPER 6; FLASH 1;
  "(2 spaces)"

You would save bytes by having your opening screen layout
load in as a SCREEN$. If you did this you could have a
whole screen-width picture to begin, changing to the stan-
dard ten characters wide with the first scroll.

 Communications Window
This is set to 30 columns wide by five rows high, with top
left corner at row 16, column 1. To alter the number of
rows POKE 63812 with the new value - 1, and 63814/5 with
the new D_FILE start address. Use Table E to find this:

  Table E.
 D_FILE at row r, column 1 :-
           Address:   low   high
 r = 12               129    72
     13               161    72
     14               193    72
     15               225    72
     16                 1    80
     17                33    80
     18                65    80
     19                97    80
     20               129    80

Obviously you /can/ make other changes but these will in-
volve drastic changes to the code. On your own head be it!
   Well, that's STRIP complete. Now engage brain and set to
work.
   Eat your heart out, Dan Dare!

[ You'll have noticed that there is no single core program
  containing and calling all the various snippets of code
  that have been scattered around these articles (mainly
  the last one). It's quite possible that had ZX Computing
  survived another month or two, Mr. Bish could have pub-
  lished a sample game using this system, but in any case
  it was not to be. This, somewhat half-organised, set of
  subroutines is all we have. It would need quite a lot of
  work to put it all together to create a real game. Still,
  it would perhaps be worth seeing the results. But for the
  time being, I'm not going to try to do so myself. ]